#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <strsafe.h>

// 链接必要的库
#pragma comment(lib, "psapi.lib")

// 配置部分
#define MAX_PROCESSES 100
#define LOG_FILE "out.txt"                 // 日志文件路径
#define MONITOR_INTERVAL 1000              // 检查间隔(毫秒)

// 进程信息结构
typedef struct {
    DWORD pid;
    char processName[MAX_PATH];
    HANDLE hProcess;
} ProcessInfo;

// 记录日志
void logActivity(const char* processName, DWORD pid, const char* filePath) {
    FILE* logFile = fopen(LOG_FILE, "a");
    if (logFile) {
        SYSTEMTIME st;
        GetLocalTime(&st);
        
        fprintf(logFile, "%04d-%02d-%02d %02d:%02d:%02d - 进程: %s (PID: %lu) 写入文件: %s\n",
                st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
                processName, pid, filePath);
        
        fclose(logFile);
    }
}

// 获取进程名称
BOOL getProcessName(DWORD pid, char* processName, DWORD size) {
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
    if (hProcess != NULL) {
        HMODULE hModule;
        DWORD cbNeeded;
        
        if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded)) {
            GetModuleFileNameExA(hProcess, hModule, processName, size);
            // 提取文件名部分
            char* fileName = strrchr(processName, '\\');
            if (fileName) {
                strcpy_s(processName, size, fileName + 1);
            }
            CloseHandle(hProcess);
            return TRUE;
        }
    }
    CloseHandle(hProcess);
    return FALSE;
}

// 查找目标进程
int findTargetProcesses(const char* targetName, ProcessInfo* processes) {
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE) {
        return 0;
    }
    
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);
    
    int count = 0;
    if (Process32First(hSnapshot, &pe32)) {
        do {
            if (_stricmp(pe32.szExeFile, targetName) == 0) {
                if (count < MAX_PROCESSES) {
                    processes[count].pid = pe32.th32ProcessID;
                    strcpy_s(processes[count].processName, MAX_PATH, pe32.szExeFile);
                    processes[count].hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
                    count++;
                }
            }
        } while (Process32Next(hSnapshot, &pe32) && count < MAX_PROCESSES);
    }
    
    CloseHandle(hSnapshot);
    return count;
}

// 监控文件系统活动
void monitorFileSystemActivity(DWORD pid, const char* processName) {
    // 创建一个文件监控对象
    HANDLE hDir = CreateFileA(
        "C:\\",                      // 监控目录
        FILE_LIST_DIRECTORY,        // 必需的访问权限
        FILE_SHARE_READ | 
        FILE_SHARE_WRITE | 
        FILE_SHARE_DELETE,          // 共享模式
        NULL,                       // 默认安全描述符
        OPEN_EXISTING,              // 打开现有目录
        FILE_FLAG_BACKUP_SEMANTICS | // 必需的标志
        FILE_FLAG_OVERLAPPED,        // 异步操作
        NULL                        // 不使用模板文件
    );
    
    if (hDir == INVALID_HANDLE_VALUE) {
        printf("无法监控目录: %d\n", GetLastError());
        return;
    }
    
    // 监控缓冲区
    char buffer[1024];
    DWORD bytesReturned;
    OVERLAPPED overlapped = {0};
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    // 开始监控
    if (!ReadDirectoryChangesW(
        hDir,                   // 目录句柄
        buffer,                 // 缓冲区
        sizeof(buffer),         // 缓冲区大小
        TRUE,                   // 监控子目录
        FILE_NOTIFY_CHANGE_FILE_NAME |
        FILE_NOTIFY_CHANGE_LAST_WRITE, // 监控文件写入
        &bytesReturned,         // 返回的字节数
        &overlapped,            // 异步操作结构
        NULL                    // 回调函数
    )) {
        printf("无法开始监控: %d\n", GetLastError());
        CloseHandle(hDir);
        CloseHandle(overlapped.hEvent);
        return;
    }
    
    // 等待监控事件
    DWORD waitResult = WaitForSingleObject(overlapped.hEvent, MONITOR_INTERVAL);
    if (waitResult == WAIT_OBJECT_0) {
        // 处理文件更改通知
        FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*)buffer;
        WCHAR fileName[MAX_PATH];
        
        // 转换为ANSI字符串
        WideCharToMultiByte(CP_ACP, 0, fni->FileName, fni->FileNameLength / sizeof(WCHAR), 
                            fileName, MAX_PATH, NULL, NULL);
        
        // 记录日志
        logActivity(processName, pid, fileName);
        
        // 重置监控
        ResetEvent(overlapped.hEvent);
        ReadDirectoryChangesW(hDir, buffer, sizeof(buffer), TRUE, 
                             FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, 
                             &bytesReturned, &overlapped, NULL);
    }
    
    // 清理资源
    CloseHandle(overlapped.hEvent);
    CloseHandle(hDir);
}

int main() {
    char target_process_name[MAX_PATH];
    
    // 询问用户要监控的进程名称
    printf("请输入要监控的进程名称 (例如: notepad.exe): ");
    if (fgets(target_process_name, MAX_PATH, stdin) == NULL) {
        printf("输入错误！\n");
        return 1;
    }
    
    // 移除换行符
    size_t len = strlen(target_process_name);
    if (len > 0 && target_process_name[len-1] == '\n') {
        target_process_name[len-1] = '\0';
    }
    
    printf("开始监控进程写入活动... 目标进程: %s\n", target_process_name);
    printf("日志将保存在: %s\n", LOG_FILE);
    
    // 创建日志文件(如果不存在)
    FILE* logFile = fopen(LOG_FILE, "a");
    if (logFile) {
        fclose(logFile);
    } else {
        printf("无法创建日志文件！\n");
        return 1;
    }
    
    // 主循环
    while (1) {
        ProcessInfo processes[MAX_PROCESSES];
        int count = findTargetProcesses(target_process_name, processes);
        
        // 监控每个目标进程
        for (int i = 0; i < count; i++) {
            monitorFileSystemActivity(processes[i].pid, processes[i].processName);
            
            // 关闭进程句柄
            if (processes[i].hProcess) {
                CloseHandle(processes[i].hProcess);
            }
        }
        
        // 等待下一次检查
        Sleep(MONITOR_INTERVAL);
    }
    
    return 0;
}    